#ifndef LRU_CACHE_H
#define LRU_CACHE_H

#include "cache_interface.h"
#include <unordered_map>
#include <list>
#include <mutex>
#include <atomic>
#include <stdexcept>

// LRU（最近最少使用）缓存实现
// 使用双向链表维护访问顺序，哈希表实现快速查找
template<typename KeyType, typename ValueType>
class LRUCache : public ICacheInterface<KeyType, ValueType> {
private:
    // 定义缓存节点类型
    using CacheNode = std::pair<KeyType, CacheEntry<ValueType>>;
    using ListIterator = typename std::list<CacheNode>::iterator;

    size_t capacity_;                                               // 缓存容量
    std::list<CacheNode> cache_list_;                              // 双向链表，存储缓存条目
    std::unordered_map<KeyType, ListIterator> cache_map_;          // 哈希表，快速查找
    mutable std::mutex cache_mutex_;                               // 保护缓存的互斥锁

    // 统计信息
    std::atomic<size_t> hit_count_;                                // 命中次数
    std::atomic<size_t> miss_count_;                               // 未命中次数
    std::atomic<size_t> total_access_;                             // 总访问次数

protected:
    // 将节点移动到链表头部（最近使用）
    void moveToFront(ListIterator it) {
        if (it != cache_list_.begin()) {
            cache_list_.splice(cache_list_.begin(), cache_list_, it);
        }
    }

    // 淘汰最久未使用的条目
    virtual void evict() {
        if (!cache_list_.empty()) {
            auto last = cache_list_.end();
            --last;

            // 在淘汰之前可以选择将数据写入下一级缓存
            onEvict(last->first, last->second.value);

            cache_map_.erase(last->first);
            cache_list_.erase(last);
        }
    }

    // 淘汰时的钩子函数，子类可以重写
    virtual void onEvict(const KeyType& key, const ValueType& value) {
        // 默认不做任何操作
    }

public:
    // 构造函数
    explicit LRUCache(size_t capacity)
        : capacity_(capacity)
        , hit_count_(0)
        , miss_count_(0)
        , total_access_(0) {
        if (capacity == 0) {
            throw std::invalid_argument("缓存容量必须大于0");
        }
    }

    // 析构函数
    virtual ~LRUCache() = default;

    // 将数据放入缓存
    virtual void put(const KeyType& key, const ValueType& value) override {
        std::lock_guard<std::mutex> lock(cache_mutex_);

        auto it = cache_map_.find(key);
        if (it != cache_map_.end()) {
            // 键已存在，更新值并移到前面
            it->second->second.value = value;
            it->second->second.timestamp = std::chrono::steady_clock::now();
            it->second->second.access_count++;
            moveToFront(it->second);
        } else {
            // 新键，检查容量
            if (cache_list_.size() >= capacity_) {
                evict();
            }

            // 插入到链表头部
            cache_list_.emplace_front(key, CacheEntry<ValueType>(value));
            cache_map_[key] = cache_list_.begin();
        }
    }

    // 从缓存中获取数据
    virtual bool get(const KeyType& key, ValueType& value) override {
        std::lock_guard<std::mutex> lock(cache_mutex_);

        total_access_++;

        auto it = cache_map_.find(key);
        if (it != cache_map_.end()) {
            // 命中，更新访问信息并移到前面
            hit_count_++;
            it->second->second.access_count++;
            it->second->second.timestamp = std::chrono::steady_clock::now();
            value = it->second->second.value;
            moveToFront(it->second);
            return true;
        } else {
            // 未命中
            miss_count_++;
            return false;
        }
    }

    // 从缓存中删除数据
    virtual void remove(const KeyType& key) override {
        std::lock_guard<std::mutex> lock(cache_mutex_);

        auto it = cache_map_.find(key);
        if (it != cache_map_.end()) {
            cache_list_.erase(it->second);
            cache_map_.erase(it);
        }
    }

    // 清空缓存
    virtual void clear() override {
        std::lock_guard<std::mutex> lock(cache_mutex_);
        cache_list_.clear();
        cache_map_.clear();
        hit_count_ = 0;
        miss_count_ = 0;
        total_access_ = 0;
    }

    // 获取缓存大小
    virtual size_t size() const override {
        std::lock_guard<std::mutex> lock(cache_mutex_);
        return cache_list_.size();
    }

    // 获取缓存容量
    virtual size_t capacity() const override {
        return capacity_;
    }

    // 获取缓存命中率
    virtual double getHitRate() const override {
        size_t total = total_access_.load();
        if (total == 0) return 0.0;
        return static_cast<double>(hit_count_.load()) / total;
    }

    // 检查键是否存在
    virtual bool contains(const KeyType& key) const override {
        std::lock_guard<std::mutex> lock(cache_mutex_);
        return cache_map_.find(key) != cache_map_.end();
    }

    // 获取统计信息
    size_t getHitCount() const { return hit_count_.load(); }
    size_t getMissCount() const { return miss_count_.load(); }
    size_t getTotalAccess() const { return total_access_.load(); }
};

#endif // LRU_CACHE_H